﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Simple.Services.System.Jobs
{
    public static class TaskManager
    {
        private static ConcurrentDictionary<string, TaskInfo> _tasks = new ConcurrentDictionary<string, TaskInfo>();
        private static ConcurrentDictionary<string, TaskTableInfo> _taskTables = new ConcurrentDictionary<string, TaskTableInfo>();
        private static ConcurrentDictionary<string, TaskCompareInfo> _taskCompares = new ConcurrentDictionary<string, TaskCompareInfo>();
        private static ConcurrentDictionary<string, TaskListCompareInfo> _taskListCompares = new ConcurrentDictionary<string, TaskListCompareInfo>();
        private static ConcurrentDictionary<string, TaskListTableInfo> _taskListTables = new ConcurrentDictionary<string, TaskListTableInfo>();
        public static void AddTask(string taskId, TaskStatus status, string excelBytes)
        {
            _tasks[taskId] = new TaskInfo { Status = status, ExcelBytes = excelBytes };
        }
        public static void AddTableTask(string taskId, TaskStatus status, List<TableReport> excelBytes)
        {
            _taskTables[taskId] = new TaskTableInfo { Status = status, Table = excelBytes };
        }
        public static void AddListTableTask(string taskId, TaskStatus status, List<TableTimeReport> excelBytes)
        {
            _taskListTables[taskId] = new TaskListTableInfo { Status = status, Table = excelBytes };
        }
        public static void AddCompareTask(string taskId, TaskStatus status, CompareReportModel excelBytes)
        {
            _taskCompares[taskId] = new TaskCompareInfo { Status = status, Compare = excelBytes };
        }
        public static void AddListCompareTask(string taskId, TaskStatus status, List<TableCompareReport> excelBytes)
        {
            _taskListCompares[taskId] = new TaskListCompareInfo { Status = status, Compare = excelBytes };
        }

        public static void CompleteTask(string taskId, string excelBytes)
        {
            if (_tasks.ContainsKey(taskId))
            {
                _tasks[taskId].Status = TaskStatus.Completed;
                _tasks[taskId].ExcelBytes = excelBytes;
            }
        }
        public static void CompleteTableTask(string taskId, List<TableReport> excelBytes)
        {
            if (_taskTables.ContainsKey(taskId))
            {
                _taskTables[taskId].Status = TaskStatus.Completed;
                _taskTables[taskId].Table = excelBytes;
            }
        }

        public static void CompleteCompareTask(string taskId, CompareReportModel excelBytes)
        {
            if (_taskCompares.ContainsKey(taskId))
            {
                _taskCompares[taskId].Status = TaskStatus.Completed;
                _taskCompares[taskId].Compare = excelBytes;
            }
        }
        public static void CompleteListCompareTask(string taskId, List<TableCompareReport> excelBytes)
        {
            if (_taskListCompares.ContainsKey(taskId))
            {
                _taskListCompares[taskId].Status = TaskStatus.Completed;
                _taskListCompares[taskId].Compare = excelBytes;
            }
        }
        public static void CompleteListTableTask(string taskId, List<TableTimeReport> excelBytes)
        {
            if (_taskListTables.ContainsKey(taskId))
            {
                _taskListTables[taskId].Status = TaskStatus.Completed;
                _taskListTables[taskId].Table = excelBytes;
            }
        }

        public static void FailTask(string taskId, string errorMessage)
        {
            if (_tasks.ContainsKey(taskId))
            {
                _tasks[taskId].Status = TaskStatus.Failed;
                _tasks[taskId].ErrorMessage = errorMessage;
            }
        }
        public static void FailTableTask(string taskId, string errorMessage)
        {
            if (_taskTables.ContainsKey(taskId))
            {
                _taskTables[taskId].Status = TaskStatus.Failed;
                _taskTables[taskId].ErrorMessage = errorMessage;
            }
        }
        public static void FailListTableTask(string taskId, string errorMessage)
        {
            if (_taskListTables.ContainsKey(taskId))
            {
                _taskListTables[taskId].Status = TaskStatus.Failed;
                _taskListTables[taskId].ErrorMessage = errorMessage;
            }
        }

        public static void FailCompareTask(string taskId, string errorMessage)
        {
            if (_taskCompares.ContainsKey(taskId))
            {
                _taskCompares[taskId].Status = TaskStatus.Failed;
                _taskCompares[taskId].ErrorMessage = errorMessage;
            }
        }
        public static void FailListCompareTask(string taskId, string errorMessage)
        {
            if (_taskListCompares.ContainsKey(taskId))
            {
                _taskListCompares[taskId].Status = TaskStatus.Failed;
                _taskListCompares[taskId].ErrorMessage = errorMessage;
            }
        }

        public static TaskInfo GetTaskStatus(string taskId)
        {
            return _tasks.ContainsKey(taskId) ? _tasks[taskId] : null;
        }
        public static TaskTableInfo GetTaskTableStatus(string taskId)
        {
            return _taskTables.ContainsKey(taskId) ? _taskTables[taskId] : null;
        }
        public static TaskListTableInfo GetTaskListTableStatus(string taskId)
        {
            return _taskListTables.ContainsKey(taskId) ? _taskListTables[taskId] : null;
        }
        public static TaskCompareInfo GetTaskCompareStatus(string taskId)
        {
            return _taskCompares.ContainsKey(taskId) ? _taskCompares[taskId] : null;
        }
        public static TaskListCompareInfo GetTaskListCompareStatus(string taskId)
        {
            return _taskListCompares.ContainsKey(taskId) ? _taskListCompares[taskId] : null;
        }

        /// <summary>
        /// 清理所有已完成的任务。
        /// </summary>
        /// <returns>返回清理的任务数量。</returns>
        public static int CleanCompletedTasks()
        {
            var completedTaskIds = _tasks
                .Where(t => t.Value.Status == TaskStatus.Completed)
                .Select(t => t.Key)
                .ToList();

            var completedTableTaskIds = _taskTables
                .Where(t => t.Value.Status == TaskStatus.Completed)
                .Select(t => t.Key)
                .ToList();
            var completedListTableTaskIds = _taskListTables
                .Where(t => t.Value.Status == TaskStatus.Completed)
                .Select(t => t.Key)
                .ToList();
            var completedCompareTaskIds = _taskCompares
                .Where(t => t.Value.Status == TaskStatus.Completed)
                .Select(t => t.Key)
                .ToList();
            var completedListCompareTaskIds = _taskListCompares
                .Where(t => t.Value.Status == TaskStatus.Completed)
                .Select(t => t.Key)
                .ToList();
            completedTaskIds.AddRange(completedTaskIds);
            completedTaskIds.AddRange(completedCompareTaskIds);
            completedTaskIds.AddRange(completedListCompareTaskIds);
            completedTaskIds.AddRange(completedListTableTaskIds);
            foreach (var taskId in completedTaskIds)
            {
                _tasks.TryRemove(taskId, out _);
            }

            return completedTaskIds.Count;
        }

        /// <summary>
        /// 清理所有已失败的任务。
        /// </summary>
        /// <returns>返回清理的任务数量。</returns>
        public static int CleanFailedTasks()
        {
            var failedTaskIds = _tasks
                .Where(t => t.Value.Status == TaskStatus.Failed)
                .Select(t => t.Key)
                .ToList();
            var failedTableTaskIds = _taskTables
                .Where(t => t.Value.Status == TaskStatus.Failed)
                .Select(t => t.Key)
                .ToList();
            var failedListTableTaskIds = _taskListTables
                .Where(t => t.Value.Status == TaskStatus.Failed)
                .Select(t => t.Key)
                .ToList();
            var failedCompareTaskIds = _taskCompares
                .Where(t => t.Value.Status == TaskStatus.Failed)
                .Select(t => t.Key)
                .ToList();
            var failedListCompareTaskIds = _taskListCompares
                .Where(t => t.Value.Status == TaskStatus.Failed)
                .Select(t => t.Key)
                .ToList();

            failedTaskIds.AddRange(failedTableTaskIds);
            failedTaskIds.AddRange(failedCompareTaskIds);
            failedTaskIds.AddRange(failedListCompareTaskIds);
            failedTaskIds.AddRange(failedListTableTaskIds);

            foreach (var taskId in failedTaskIds)
            {
                _tasks.TryRemove(taskId, out _);
            }

            return failedTaskIds.Count;
        }

        /// <summary>
        /// 清理所有任务。
        /// </summary>
        public static void CleanAllTasks()
        {
            _tasks.Clear();
            _taskTables.Clear();
            _taskCompares.Clear();
            _taskListCompares.Clear();
            _taskListTables.Clear();
        }
    }

    public class TaskInfo
    {
        public TaskStatus Status { get; set; }
        public string ExcelBytes { get; set; }
        public string ErrorMessage { get; set; }
    }
    public class TaskTableInfo
    {
        public TaskStatus Status { get; set; }
        public List<TableReport> Table { get; set; }
        public string ErrorMessage { get; set; }
    }

    public class TaskCompareInfo
    {
        public TaskStatus Status { get; set; }
        public CompareReportModel Compare { get; set; }
        public string ErrorMessage { get; set; }
    }
    public class TaskListCompareInfo
    {
        public TaskStatus Status { get; set; }
        public List<TableCompareReport> Compare { get; set; }
        public string ErrorMessage { get; set; }
    }
    public class TaskListTableInfo
    {
        public TaskStatus Status { get; set; }
        public List<TableTimeReport> Table { get; set; }
        public string ErrorMessage { get; set; }
    }

    public enum TaskStatus
    {
        Running,
        Completed,
        Failed
    }

}
